(function(global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('moment'), require('../frontend/jsonview')) :
    typeof define === 'function' && define.amd ? define(['moment', 'jsonview'], factory) :
    global.log = factory(moment, jsonview);
}(this, function(moment, jsonview) {

  function timestamp() {
    return moment().format('YYYY-MM-DD HH:mm:ss,SSSZ');
  }

  var isbrowser = (typeof navigator != "undefined" ? true : false);

  function tlog(type) {
    function ret() {}
    ret.valueOf = ret.toString = function() {
      return [timestamp(), '<' + type + '>'].join(' ');
    }
    return ret;
  }

  var log = null;
  if (isbrowser) {
    log = console.log.bind(console, tlog('log'));

    ['info', 'debug', 'warn', 'error'].forEach(function(type) {
      log[type] = console[type].bind(console, tlog(type));
    });

    log.getLogger = function(elem) {
      var clog = function(elem) {
        if (!elem) {
          elem = document.createElement('div');
          document.body.appendChild(elem);
        }
        this.elem = elem;
      };
      ['info', 'debug', 'warn', 'error'].forEach(function(type) {
        clog.prototype[type] = function() {
          var childNodes = document.createElement('p');
          
          var child = document.createElement('span');
          child.style.marginRight = '2em';
          child.innerHTML = [timestamp(), '&lt;' + type + '&gt;'].join(' ');
          childNodes.appendChild(child);

          Array.prototype.slice.call(arguments).forEach(function(param) {
            child = document.createElement('span');
            child.innerHTML = jsonview(param);
            childNodes.appendChild(child);
          });
          this.elem.appendChild(childNodes);
          return this;
        } 
      });
      return new clog(elem);
    }
  } else {
    var logger = require('tracer').colorConsole();
    log = logger.log;

    ['info', 'debug', 'warn', 'error'].forEach(function(type) {
      log[type] = logger[type];
    });
  }

  return log;

}))
